package engine;

import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.World;

import font.GLFont;

public class Universe implements IEntity {
	private static final int MIN_SEND_POINTS = 1;

	private int victory;
	
	private List<Planet> planets;
	private int playerPlanetCounter;
	private int enemyPlanetCounter;
	private float aggressivness;

	private List<Ship> ships;
	private List<Ship> shipsToRemove;

	private EventHandler eventHandler;

	private DifficultyLevel difficultyLevel;

	private World world;

	private static GLFont font;

	public Universe() {
		planets = new ArrayList<Planet>();
		setVictory(0);
		ships = new ArrayList<Ship>();
		shipsToRemove = new ArrayList<Ship>();
		difficultyLevel = new DifficultyLevel(DifficultyLevel.HARD);
		font = new GLFont(new Font("Arial", Font.PLAIN, 16));
	}

	public void addPlanet(Planet p) {
		planets.add(p);
	}

	public void addShip(Ship s) {
		ships.add(s);
	}

	public World getWorld() {
		return world;
	}

	public List<Planet> getPlanets() {
		return planets;
	}

	@Override
	public void onInit(World world, FrameBuffer buffer) {
		aggressivness = 0.5f;
		eventHandler = new EventHandler(world, buffer, this);
		this.world = world;

		for (Planet planet : getPlanets())
			planet.onInit(world, buffer);

		AIPlayer ai = new AIPlayer(this, difficultyLevel);
		ai.start();
	}

	@Override
	public void onUpdate(World world, FrameBuffer buffer) {
		eventHandler.handle();

		playerPlanetCounter = 0;
		enemyPlanetCounter = 0;

		for (Planet planet : planets) {
			planet.onUpdate(world, buffer);

			switch (planet.getOwner()) {
			case PLAYER:
				playerPlanetCounter++;
				break;
			case ENEMY:
				enemyPlanetCounter++;
				break;
			}
		}

		if (playerPlanetCounter == 0 && !isShipsExist(Ownership.PLAYER)) {
			enemyWon();
		} else if (enemyPlanetCounter == 0 && !isShipsExist(Ownership.ENEMY)) {
			playerWon();
		}

		for (int i = 0; i < ships.size(); i++)
			ships.get(i).onRenderUpdate(world, buffer);

		font.blitString(buffer, "A: " + getAggressivnessAsPercent(aggressivness), 700, 30, 100, Color.WHITE);
	}

	private boolean isShipsExist(Ownership owner) {
		for (int i = 0; i < ships.size(); i++){
			if (ships.get(i).getOwner() == owner)
				return true;
		}
		return false;
	}

	private String getAggressivnessAsPercent(float a) {
		int percent = (int) (a * 100);
		return percent + "%";
	}

	public void onLogicUpdate(World world, FrameBuffer buffer) {
		for (int i=0; i<ships.size(); i++) {
			ships.get(i).onUpdate(world, buffer);

			if (ships.get(i).isShipArrived()) {
				ships.get(i).destroy(world);
				shipsToRemove.add(ships.get(i));
			}
		}
		ships.removeAll(shipsToRemove);
	}

	public void onDragBetweenPlanets(Planet src, Planet dest) {
		if (src.getPoints() > MIN_SEND_POINTS && src.getOwner() == Ownership.PLAYER) {
			Ship ship = new Ship(world, src, dest, (int) (src.getPoints() * aggressivness));
			ship.setOwner(Ownership.PLAYER);
			ships.add(ship);
		}
	}
	
	private void playerWon(){
		setVictory(1);

	}
	
	private void enemyWon(){
		setVictory(-1);
	}

	public void onAggressivnessChange(float a) {
		//Logger.log("Agg changed: " + a);
		aggressivness = a;
	}

	public int getVictory() {
		return victory;
	}

	public void setVictory(int victory) {
		this.victory = victory;
	}
	
	public void stopPointIncrementation(){
		for(int i = 0; i < planets.size(); i++)
			planets.get(i).stopPointIncrementation();
	}
	
	public void startPointIncrementation(){
		for(int i = 0; i < planets.size(); i++)
			planets.get(i).startPointIncrementation();
	}
}
